{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Compiling the RISC-V GCC Toolchain on your PYNQ Board\n",
    "\n",
    "This notebook describes the steps to compile the RISC-V GCC Toolchain on your PYNQ Board. This depends on the steps in **[Downloading Dependencies](1-Downloading-And-Configuring.ipynb)**. You must complete the steps in that notebook before attempting this notebook.\n",
    "\n",
    "This notebook is run entirely on a PYNQ board. The cells within this notebook will take several hours to finish - so be patient. On the bright side, this notebook can (and should) be run in parallel with the host-based **[Creating a FPGA Bitstream](2-Creating-A-Bitstream.ipynb)**.\n",
    "\n",
    "These cells are based on the instructions provided in the [riscv-gnu-toolchain repository](https://github.com/riscv/riscv-gnu-toolchain)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Verifying the riscv-gnu-toolchain Repository\n",
    "\n",
    "You must have the riscv-gnu-toolchain repository cloned in order for this notebook to run. The following cell checks for the existence of the riscv-gnu-toolchain git repository in the `/home/xilinx` folder on the PYNQ board.\n",
    "\n",
    "If these commands fail return to **[Downloading Dependencies and Configuring your Environment](1-Downloading-And-Configuring.ipynb)** and re-run the steps there."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total 328K\r\n",
      "drwxr-xr-x 16 root root 4.0K Nov 16 21:21 build-binutils-newlib\r\n",
      "drwxr-xr-x 11 root root 4.0K Nov 16 22:39 build-gcc-newlib-stage1\r\n",
      "drwxr-xr-x 13 root root 4.0K Nov 17 05:26 build-gcc-newlib-stage2\r\n",
      "drwxr-xr-x  4 root root 4.0K Nov 17 01:51 build-newlib\r\n",
      "-rw-r--r--  1 root root 9.3K Nov 16 20:51 config.log\r\n",
      "-rwxr-xr-x  1 root root  25K Nov 16 20:51 config.status\r\n",
      "-rwxr-xr-x  1 root root 129K Nov 16 18:46 configure\r\n",
      "-rw-r--r--  1 root root 5.2K Nov 16 18:46 configure.ac\r\n",
      "-rw-r--r--  1 root root  41K Nov 16 18:46 LICENSE\r\n",
      "drwxr-xr-x  3 root root 4.0K Nov 16 18:46 linux-headers\r\n",
      "-rw-r--r--  1 root root  20K Nov 16 20:51 Makefile\r\n",
      "-rw-r--r--  1 root root  20K Nov 16 18:46 Makefile.in\r\n",
      "-rw-r--r--  1 root root 4.1K Nov 16 18:46 README.md\r\n",
      "drwxr-xr-x  2 root root 4.0K Nov 16 18:46 regression\r\n",
      "drwxr-xr-x 22 root root 4.0K Nov 16 19:00 riscv-binutils-gdb\r\n",
      "drwxr-xr-x  8 root root 4.0K Nov 16 19:00 riscv-dejagnu\r\n",
      "drwxr-xr-x 37 root root 4.0K Nov 16 19:58 riscv-gcc\r\n",
      "drwxr-xr-x 69 root root 4.0K Nov 16 20:09 riscv-glibc\r\n",
      "drwxr-xr-x  9 root root 4.0K Nov 16 20:11 riscv-newlib\r\n",
      "drwxr-xr-x  3 root root 4.0K Nov 16 18:46 scripts\r\n",
      "drwxr-xr-x  2 root root 4.0K Nov 17 05:56 stamps\r\n",
      "drwxr-xr-x  7 root root 4.0K Nov 16 18:46 test\r\n"
     ]
    }
   ],
   "source": [
    "!ls -lh /home/xilinx/riscv-gnu-toolchain"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Building the RISC-V Tools\n",
    "\n",
    "Now that we've met all our dependencies, we need to compile and install the tools. In the next two cells we build, and then install the tools. \n",
    "\n",
    "Once the tools have been compiled you will need to modify the Linux environment PATH variable and then reboot your board in order for the change to take effect. Once you can, we verify the tools and complete the notebook.\n",
    "\n",
    "If you want to monitor the progress of your compilation you can read the config.log and build.log file that is generated during. You can read the logs by opening [cnfig.log](cnfig.log) and [build.log](build.log) by clicking the links or by opening them in the [Jupyter Browser](.). Update the logs by running refresh periodically.\n",
    "\n",
    "Alternatively, you can also view the logs by opening a terminal by clicking [here](../../../terminals/42) or by navigating to (**Jupyter Home** > **New** > **Terminal**) and then running the commands: \n",
    "    \n",
    "    less /home/xilinx/jupyter_notebooks/RISC-V-Tutorial/config.log\n",
    "\n",
    "or\n",
    "\n",
    "    less /home/xilinx/jupyter_notebooks/RISC-V-Tutorial/build.log"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Configuration successful!\n"
     ]
    }
   ],
   "source": [
    "from subprocess import run, PIPE, Popen\n",
    "\n",
    "cnfig_log = open(\"cnfig.log\",\"w\")\n",
    "cnfig_err = open(\"cnfig.err\",\"w\")\n",
    "\n",
    "ret = run([\"./configure\", \"--prefix=/opt/riscv32im\", \"--with-arch=rv32im\"], \n",
    "          cwd=\"/home/xilinx/riscv-gnu-toolchain/\",\n",
    "          stdout=cnfig_log, stderr=cnfig_err)\n",
    "cnfig_log.close()\n",
    "cnfig_err.close()\n",
    "\n",
    "if(ret.returncode != 0):\n",
    "    print(\"There was an error while configuring the RISCV Toolchain. See the config.err and config.log file\")\n",
    "else:\n",
    "    print(\"Configuration successful!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Compile successful!\n"
     ]
    }
   ],
   "source": [
    "build_log = open(\"build.log\",\"w\")\n",
    "build_err = open(\"build.err\",\"w\")    \n",
    "ret = run([\"make\"], \n",
    "          cwd=\"/home/xilinx/riscv-gnu-toolchain/\",\n",
    "          stdout=build_log, stderr=build_err)\n",
    "build_log.close()\n",
    "build_err.close()\n",
    "\n",
    "if(ret.returncode != 0):\n",
    "    print(\"There was an error while compiling the RISCV Toolchain. See the build.err and build.log file\")\n",
    "else:\n",
    "    print(\"Compile successful!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Modifying PATH\n",
    "\n",
    "Now that the tools have been installed we need to add them to the PATH variable so that they can be run from Jupyter Notebooks and the command line. To do this we will modify the `/etc/environment` file using the cell below.\n",
    "\n",
    "If the PATH already contains the folder with the RISC-V GCC binaries this command will succeed but make no changes.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Updating /etc/environment file... done\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "path = os.environ['PATH'].split()\n",
    "riscv_path = '/opt/riscv32im/bin'\n",
    "if(riscv_path not in path):\n",
    "    print('Updating /etc/environment file... ',end=\"\")\n",
    "    !sed -i 's/PATH=\\\"\\(.*\\)\\\"/PATH=\\\"\\/opt\\/riscv32im\\/bin:\\1\\\"/' /etc/environment\n",
    "    print('done')\n",
    "else:\n",
    "    print(\"/etc/environment file already updated\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Reboot...\n",
    "\n",
    "Reboot your board once the cell above has run. When your board finishes rebooting refresh this page and proceed to the next cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!shutdown -r now"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Verify Installation\n",
    "\n",
    "\n",
    "The following cell verifies that the RISC-V Toolchain has been successfully installed. If you see an error message, make sure that your toolchain compiliation completed succesffully.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "riscv32-unknown-elf-gcc (GCC) 7.1.1 20170509\r\n",
      "Copyright (C) 2017 Free Software Foundation, Inc.\r\n",
      "This is free software; see the source for copying conditions.  There is NO\r\n",
      "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r\n",
      "\r\n"
     ]
    }
   ],
   "source": [
    "!riscv32-unknown-elf-gcc --version"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
